package com.xiaobaibai.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaobaibai.common.IndexEnum;
import com.xiaobaibai.entity.Category;
import com.xiaobaibai.entity.IndexDetail;
import com.xiaobaibai.entity.IndexProduct;
import com.xiaobaibai.entity.Product;
import com.xiaobaibai.response.ResponseFormat;
import com.xiaobaibai.service.*;
import com.xiaobaibai.valid.AddGroup;
import com.xiaobaibai.valid.UpdateGroup;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Delete;
import org.assertj.core.data.Index;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@Api(tags = "商品管理相关接口")
@RequestMapping("/product")
@CrossOrigin
public class ProductController {

    @Autowired
    private IProductService productService;

    @Autowired
    private IIndexProductService indexProductService;

    @Autowired
    private ICategoryService categoryService;

    @Autowired
    private IEsService esService;

    @GetMapping("/list")
    @ApiOperation("(弃用)获取所有商品->页码,页容量,排序字段,排序规则")
    public ResponseFormat getProductList(@RequestParam(defaultValue = "1",required = false) Integer pageNum,
                                        @RequestParam(defaultValue = "10",required = false) Integer pageSize,
                                        @RequestParam(required = false)Integer categoryId,
                                        @RequestParam(required = false,defaultValue = "true")Boolean status,
                                        @RequestParam(required = false)String search,
                                        @RequestParam(required = false)String orderBy,
                                        @RequestParam(required = false)String sort){
        //前端做1.排序:   价格/销量  默认是根据id
        //前端做2.分类(注意大分类和小分类):  分类即可
        //前端做3.上下架: 查询即可
        //前端做4.页码:   分页即可
        //后端做4.模糊搜索: 根据es搜索 (排序+分类+上下架) 高级聚合
        //5.总之: 分为mysql查询和es查询
        //6.警告: es的数据不是实时的,那么又要查询一次mysql,就不是很好
        //7.妥协: 那就再查一次mysql,先模糊搜索出id集合,然后mysql查id集合

        long start=System.currentTimeMillis();

        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();

        if (search!=null){
            List<Integer> list = haveSearch(search);
            if(list.size()!=0)
                queryWrapper.in("id",list);
            else
                return ResponseFormat.ok("获取商品数据成功",new ArrayList<>());
        }

        if(orderBy!=null) {//排序
            if(StringUtils.equalsIgnoreCase("desc",sort))
                queryWrapper.orderBy(true, false, orderBy);//降序
            else
                queryWrapper.orderBy(true, true, orderBy);//降序
        }

        queryWrapper.eq("product_status",status);//上下架

        if(categoryId!=null)//分类
            queryWrapper.eq("category",categoryId);

        IPage<Product> page=new Page<>(pageNum,pageSize);//分页
        IPage<Product> list = productService.page(page, queryWrapper);

        List<Product> productList = list.getRecords();

        haveNewOrHot(productList);

        System.out.println(System.currentTimeMillis()-start+"毫秒");

        return ResponseFormat.ok("获取商品数据成功",productList);
    }

    /**
     * 1.传过去所有数据
     * 2.所有排序由前端来完成
     * 3.(上下架+热销+新品)三条件过滤由前端完成
     * 4.模糊搜索+分类查询后端完成
     */
    @GetMapping("/list2")
    @ApiOperation("获取所有商品版本二")
    public ResponseFormat getProductList2(@RequestParam(required = false)String search,
                                          @RequestParam(required = false)Integer categoryId){

        List<Integer> ids=null;
        if(StringUtils.isNotBlank(search)) {
            ids = haveSearch(search);
            if(ids.size()==0)
                return ResponseFormat.ok("搜索数据为空",new ArrayList<>(0));
        }

        List<Category> categorys=null;
        if(categoryId!=null&&categoryId>0){
            QueryWrapper<Category> categoryQueryWrapper=new QueryWrapper<>();
            categoryQueryWrapper.eq("id",categoryId).or().eq("category_p_id",categoryId);
            categoryQueryWrapper.select("id");
            //就算mysql没有数据,返回的是一个size为0的list
            categorys = categoryService.list(categoryQueryWrapper);
        }

        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        if(ids!=null)
            queryWrapper.in("id",ids);
        if(categorys!=null&&categorys.size()!=0) {
            List<Integer> categoryIds=new ArrayList<>(categorys.size());
            categorys.forEach(c->{
                categoryIds.add(c.getId());
            });
            queryWrapper.in("category_id",categoryIds);
        }

        queryWrapper.select("id","category_id","product_image",
                "product_name","product_old_price","product_price",
                "product_sales","product_status","product_stock","product_unit");

        List<Product> list = productService.list(queryWrapper);

        haveNewOrHot(list);

        return ResponseFormat.ok("获取商品数据成功",list);
    }

    private List<Integer> haveSearch(String productName){
        return productService.searchByEs(productName);
    }

    private void haveNewOrHot(List<Product> list){

        QueryWrapper<IndexProduct> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("product_id","type");
        List<IndexProduct> indexProductsList= indexProductService.list(queryWrapper);
        Set newSet=new HashSet();
        Set hotSet=new HashSet();
        indexProductsList.forEach(i->{
            if(i.getType().equals(IndexEnum.XINPIN.getCode())){
                newSet.add(i.getProductId());
            }
            if(i.getType().equals(IndexEnum.REXIAO.getCode())){
                hotSet.add(i.getProductId());
            }
        });
        list.forEach(p->{
            if(newSet.contains(p.getId()))
                p.setNewProduct(true);
            if(hotSet.contains(p.getId()))
                p.setHotProduct(true);
        });

    }

    @GetMapping("/oneProduct")
    @ApiOperation("根据商品id获取单个商品")
    public ResponseFormat getOneProduct(@RequestParam(value = "id")Integer id){

        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",id);
        Product one = productService.getOne(queryWrapper);
        if(one==null)
            return ResponseFormat.ok("商品不存在");
        List<Product> list=new ArrayList<>();
        list.add(one);
        haveNewOrHot(list);
        one=list.get(0);
        return ResponseFormat.ok("获取单个商品信息成功",one);
    }

    @PostMapping("/do-product")
    @ApiOperation("增加商品")
    @CacheEvict(value = "product",key = "'getAllList'")
    public ResponseFormat addProduct(@RequestBody @Validated(value = AddGroup.class)
                                     Product product){
        boolean flag = productService.save(product);
        if(!flag)
            return ResponseFormat.failure("新增商品失败");
        //查看新增时是否选择了新品推荐或者热销推荐
        hotOrNew(product);
        esService.addProduct(product);
        return ResponseFormat.ok("新增商品成功",product);
    }

    @PutMapping("/do-product")
    @ApiOperation("修改商品")
    public ResponseFormat updateProduct(@RequestBody @Validated(value = UpdateGroup.class) Product product){
        product.setProductVersion(null);
        boolean flag = productService.updateById(product);
        //对应的新品推荐和热销推荐的价格也需要更改  (看后面时间够不够吧)  不改了!
        if(!flag)
            return ResponseFormat.failure("修改商品失败");
        //可能有新增新品或者新增热销,也可能是取消
        if(product.getNewProduct()){
            indexProductService.addIndexProduct(Arrays.asList(product.getId()),IndexEnum.XINPIN);
        }else{
            indexProductService.deleteNewByIds(Arrays.asList(product.getId()),IndexEnum.XINPIN.getCode());
        }
        if(product.getHotProduct()){
            indexProductService.addIndexProduct(Arrays.asList(product.getId()),IndexEnum.REXIAO);
        }else{
            indexProductService.deleteNewByIds(Arrays.asList(product.getId()),IndexEnum.REXIAO.getCode());
        }
        esService.updateProduct(product);
        return ResponseFormat.ok("修改商品成功");
    }

    @DeleteMapping("/do-product")
    @ApiOperation("删除商品")
    public ResponseFormat deleteProduct(@RequestParam(value = "id")Integer id){
        boolean flag = productService.removeById(id);
        if(!flag)
            return ResponseFormat.failure("删除商品失败");
        //直接删除对应商品推荐表的
        Map<String,Object> map = new HashMap<>();
        map.put("product_id", id);
        indexProductService.removeByMap(map);
        esService.deleteProduct(id);
        return ResponseFormat.ok("删除商品成功");
    }

    private void hotOrNew(Product product){
        List<IndexProduct> list=new ArrayList<>(2);
        if(product.getHotProduct()!=null){
            if(product.getHotProduct()){
                IndexProduct indexProduct=new IndexProduct();
                indexProduct.setStatus(true);
                indexProduct.setProductId(product.getId());
                indexProduct.setProductName(product.getProductName());
                indexProduct.setProductImage(product.getProductImage().get(0));//0是主图
                indexProduct.setProductOldPrice(product.getProductOldPrice());
                indexProduct.setProductPrice(product.getProductPrice());
                indexProduct.setProductUnit(product.getProductUnit());
                indexProduct.setType(IndexEnum.REXIAO.getCode());
                list.add(indexProduct);
            }
        }
        if(product.getNewProduct()!=null){
            if(product.getNewProduct()){
                IndexProduct indexProduct=new IndexProduct();
                indexProduct.setStatus(true);
                indexProduct.setProductName(product.getProductName());
                indexProduct.setProductId(product.getId());
                indexProduct.setProductImage(product.getProductImage().get(0));
                indexProduct.setProductPrice(product.getProductPrice());
                indexProduct.setProductOldPrice(product.getProductOldPrice());
                indexProduct.setProductUnit(product.getProductUnit());
                indexProduct.setType(IndexEnum.XINPIN.getCode());
                list.add(indexProduct);
            }
        }
        if(list.size()!=0)
            indexProductService.saveBatch(list);
    }

    //联想搜索词
    @GetMapping("/associatedWords")
    @ApiOperation("联想搜索,传入前缀")
    public ResponseFormat associatedWords(String search){

        List<String> list = productService.associatedWords(search);

        return ResponseFormat.ok("联想词",list);

    }

    @PostMapping("/status")
    @ApiOperation("批量商品上架")
    public ResponseFormat upStatusList(@RequestBody List<Integer> list){
        List<Product> productList=new ArrayList<>();
        list.forEach(l->{
            Product product=new Product();
            product.setId(l);
            product.setProductStatus(true);
        });
        productService.updateBatchById(productList);
        esService.updateProductStatus(list,true);
        return ResponseFormat.ok("商品上架成功");
    }

    @DeleteMapping("/status")
    @ApiOperation("批量商品下架")
    public ResponseFormat downStatusList(@RequestBody List<Integer> list){
        List<Product> productList=new ArrayList<>();
        list.forEach(l->{
            Product product=new Product();
            product.setId(l);
            product.setProductStatus(false);
        });
        productService.updateBatchById(productList);
        esService.updateProductStatus(list,true);
        return ResponseFormat.ok("商品下架成功");
    }

}
